package com.aotain.ticket;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Scanner;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.json.JSONException;
import org.json.JSONObject;

public class Ticket {
	private HttpsURLConnection conn = null;
	private String sessionId = "";
	private String randCode = "";

	private static class TrustAnyTrustManager implements X509TrustManager {

		public void checkClientTrusted(X509Certificate[] chain, String authType)
				throws CertificateException {
		}

		public void checkServerTrusted(X509Certificate[] chain, String authType)
				throws CertificateException {
		}

		public X509Certificate[] getAcceptedIssuers() {
			return new X509Certificate[] {};
		}
	}

	private static class TrustAnyHostnameVerifier implements HostnameVerifier {
		public boolean verify(String hostname, SSLSession session) {
			return true;
		}
	}

	/**
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		Ticket ticket = new Ticket();
		ticket.begin();
	}

	private void begin() throws Exception {
		Map param = new HashMap();

		getMessage("https://dynamic.12306.cn/otsweb/");

		param.clear();
		String a = send(
				"https://dynamic.12306.cn/otsweb/loginAction.do?method=loginAysnSuggest",
				param);
		JSONObject jsob = new JSONObject(a);

		downImg();
		getRand();

		login(param, jsob);

	}

	/**
	 * @param param
	 * @param jsob
	 * @throws JSONException
	 */
	private void login(Map param, JSONObject jsob) throws JSONException {
		String a;
		param.clear();
		param.put("loginRand", jsob.get("loginRand"));
		param.put("refundLogin", "N");
		param.put("refundFlag", "Y");
		param.put("loginUser.user_name", readPro("username"));
		param.put("nameErrorFocus", "");
		param.put("user.password", readPro("password"));
		param.put("passwordErrorFocus", "");
		param.put("randCode", randCode);
		param.put("randErrorFocus", "");
		a = send("https://dynamic.12306.cn/otsweb/loginAction.do?method=login",
				param);
		System.out.println(a);
		if (a.indexOf("请输入正确的验证码") > -1) {
			System.out.println("验证码输入错误");
			downImg();
			getRand();
			login(param, jsob);
		} else if (a.indexOf("欢迎您登录") != -1) {
			System.out.println("登陆成功");
		} else if (a.indexOf("密码输入错误") != -1) {
			System.out.println("密码错误");
			downImg();
			getRand();
			login(param, jsob);
		} else {
			login(param, jsob);
		}
	}

	/**
	 * 读取配置 文件
	 * 
	 * @param name
	 * @return
	 */
	private String readPro(String name) {
		InputStream inputStream = this.getClass().getClassLoader()
				.getResourceAsStream("config.properties");
		Properties p = new Properties();
		try {
			p.load(inputStream);
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		return p.getProperty(name);
	}

	/**
	 * 发送post请求
	 * 
	 * @param urlAddr
	 * @param map
	 * @return
	 */
	private String send(String urlAddr, Map map) {

		StringBuffer params = new StringBuffer();

		Iterator it = map.entrySet().iterator();
		while (it.hasNext()) {
			Entry element = (Entry) it.next();
			params.append(element.getKey());
			params.append("=");
			params.append(element.getValue());
			params.append("&");
		}

		if (params.length() > 0) {
			params.deleteCharAt(params.length() - 1);
		}

		try {
			URL url = new URL(urlAddr);
			SSLContext sc = SSLContext.getInstance("SSL");
			sc.init(null, new TrustManager[] { new TrustAnyTrustManager() },
					new java.security.SecureRandom());
			conn = (HttpsURLConnection) url.openConnection();
			conn.setSSLSocketFactory(sc.getSocketFactory());
			if (sessionId.length() > 0) {
				conn.setRequestProperty("Cookie", sessionId);
			}
			conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
			conn.setDoOutput(true);
			conn.setRequestMethod("POST");
			conn.setUseCaches(false);
			conn.setRequestProperty("Content-Type",
					"application/x-www-form-urlencoded");
			conn.setRequestProperty("Content-Length",
					String.valueOf(params.length()));
			conn.setDoInput(true);
			conn.connect();
			OutputStreamWriter out = new OutputStreamWriter(
					conn.getOutputStream(), "UTF-8");
			out.write(params.toString());
			out.flush();
			out.close();
			String cookieVal = null;

			String key = null;
			for (int i = 1; (key = conn.getHeaderFieldKey(i)) != null; i++) {
				if (key.equalsIgnoreCase("set-cookie")) {
					cookieVal = conn.getHeaderField(i);
					cookieVal = cookieVal.substring(0, cookieVal.indexOf(";"));
					sessionId = sessionId + cookieVal + ";";
				}
			}

			InputStream is = conn.getInputStream();
			DataInputStream indata = new DataInputStream(is);
			String ret = "";
			String str_return = "";
			while (ret != null) {
				ret = indata.readLine();
				if (ret != null && !ret.trim().equals("")) {
					str_return = str_return
							+ new String(ret.getBytes("ISO-8859-1"), "UTF-8");
				}
			}
			return str_return;

		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return null;
	}

	private String getMessage(String urlAddr) {

		try {
			URL url = new URL(urlAddr);
			SSLContext sc = SSLContext.getInstance("SSL");
			sc.init(null, new TrustManager[] { new TrustAnyTrustManager() },
					new java.security.SecureRandom());
			conn = (HttpsURLConnection) url.openConnection();
			conn.setSSLSocketFactory(sc.getSocketFactory());
			if (sessionId.length() > 0) {
				conn.setRequestProperty("Cookie", sessionId);
			}
			conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
			conn.setDoOutput(true);
			conn.setRequestMethod("GET");
			conn.setUseCaches(false);
			conn.setRequestProperty("Content-Type",
					"application/x-www-form-urlencoded");
			conn.setDoInput(true);
			conn.connect();
			String cookieVal = null;

			String key = null;
			for (int i = 1; (key = conn.getHeaderFieldKey(i)) != null; i++) {
				if (key.equalsIgnoreCase("set-cookie")) {
					cookieVal = conn.getHeaderField(i);
					cookieVal = cookieVal.substring(0, cookieVal.indexOf(";"));
					sessionId = sessionId + cookieVal + ";";
				}
			}

			InputStream is = conn.getInputStream();
			DataInputStream indata = new DataInputStream(is);
			String ret = "";
			String str_return = "";
			while (ret != null) {
				ret = indata.readLine();
				if (ret != null && !ret.trim().equals("")) {
					str_return = str_return
							+ new String(ret.getBytes("ISO-8859-1"), "UTF-8");
				}
			}
			return str_return;

		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return null;
	}

	/**
	 * 下载验证码
	 */
	private void downImg() {
		try {
			URL url = new URL(
					"https://dynamic.12306.cn/otsweb/passCodeAction.do?rand=sjrand");
			File outFile = new File("rand.jpg");
			OutputStream os = new FileOutputStream(outFile);
			SSLContext sc = SSLContext.getInstance("SSL");
			sc.init(null, new TrustManager[] { new TrustAnyTrustManager() },
					new java.security.SecureRandom());
			conn = (HttpsURLConnection) url.openConnection();
			conn.setSSLSocketFactory(sc.getSocketFactory());
			if (sessionId.length() > 0) {
				conn.setRequestProperty("Cookie", sessionId);
			}
			InputStream is = conn.getInputStream();
			byte[] buff = new byte[1024];
			while (true) {
				int readed = is.read(buff);
				if (readed == -1) {
					break;
				}
				byte[] temp = new byte[readed];
				System.arraycopy(buff, 0, temp, 0, readed);
				os.write(temp);
			}
			is.close();
			os.close();
		} catch (Exception ex) {

		}
	}

	private void getRand() {
		System.out.println("please input the rand code:");
		Scanner sc = new Scanner(System.in);
		randCode = sc.next();
	}
}
